﻿using System;
using System.Text.RegularExpressions;

namespace RecruitmentAgency.Models.Validation
{
    /// <summary>
    /// Contains validation common methods
    /// </summary>
    public class BaseValidator
    {
        /// <summary>
        /// Represents the message that is displayed in drop down lists when no value has been selected by the user
        /// </summary>
        protected string selectMessage;

        /// <summary>
        /// Initialises a new RecruitmentAgency.Validation.BaseValidator instance
        /// </summary>
        public BaseValidator(string selectMessage)
        {
            this.selectMessage = selectMessage;
        }

        /// <summary>
        /// Validates whether the input string is empty
        /// </summary>
        /// <param name="field">The string to be validated</param>
        /// <returns>Returns true if the input string is empty and false if not</returns>
        protected bool IsEmpty(string field)
        {
            return field.Length == 0;
        }

        /// <summary>
        /// Validates whether the input string is the select message and therefore has no value
        /// </summary>
        /// <param name="selection">The string to be validated</param>
        /// <returns>Returns true if the input string is the select message and therefore has no value and false if not</returns>
        protected bool ValidateSelection(string selection)
        {
            return selection == selectMessage;
        }

        /// <summary>
        /// Validates whether the input string represents a landline-based phone number
        /// </summary>
        /// <param name="homePhone">The string to be validated</param>
        /// <returns>Returns true if the input string is not a valid landline-based phone number and false if it is</returns>
        protected bool ValidateHomePhone(string homePhone)
        {
            return homePhone.Length > 0 && !Regex.IsMatch(homePhone, @"^\d{3,5}[\s-]*\d{3,4}[\s-]*\d{3,4}$");
        }

        /// <summary>
        /// Validates whether the input string represents a mobile-based phone number
        /// </summary>
        /// <param name="mobilePhone">The string to be validated</param>
        /// <returns>Returns true if the input string is not a valid mobile-based phone number and false if it is</returns>
        protected bool ValidateMobilePhone(string mobilePhone)
        {
            return mobilePhone.Length > 0 && !Regex.IsMatch(mobilePhone, @"^\d{5}[\s-]*\d{3}[\s-]*\d{3}$");
        }

        /// <summary>
        /// Validates whether the input string represents an e-mail address
        /// </summary>
        /// <param name="email">The string to be validated</param>
        /// <returns>Returns true if the input string is not a valid e-mail address and false if it is</returns>
        protected bool ValidateEmail(string email)
        {
            return email.Length > 0 && !Regex.IsMatch(email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
        }

        /// <summary>
        /// Validates whether the input string represents a URL
        /// </summary>
        /// <param name="url">The string to be validated</param>
        /// <returns>Returns true if the input string is not a valid URL and false if it is</returns>
        protected bool ValidateUrl(string url)
        {
            string pattern = @"^((http|https|ftp)\://)?(www\.)?[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?$";
            return url.Length > 0 && !Regex.IsMatch(url.ToLower(), pattern);
        }

        /// <summary>
        /// Validates whether the input string represents a year
        /// </summary>
        /// <param name="year">The string to be validated</param>
        /// <returns>Returns true if the input string is not a valid year and false if it is</returns>
        protected bool ValidateYear(string year)
        {
            int result;
            int.TryParse(year, out result);
            if (result < 1900 || result > DateTime.Now.Year) return true;
            return false;
        }

        /// <summary>
        /// Validates whether the input strings represent dates
        /// </summary>
        /// <param name="startDate">The start date string to be validated</param>
        /// <param name="endDate">The end date string to be validated</param>
        /// <returns>Returns true if the input strings are not both valid dates or the end date is before the start date. It returns false if the two input strings represent valid dates and the start date is before the end date</returns>
        protected bool ValidateDates(string startDate, string endDate)
        {
            DateTime startResult, endResult;
            DateTime.TryParse(startDate, out startResult);
            DateTime.TryParse(endDate, out endResult);
            if (startResult == DateTime.MinValue || endResult == DateTime.MinValue) return true;
            if (startResult > endResult) return true;
            return false;
        }

        /// <summary>
        /// Validates whether the input string represents a date
        /// </summary>
        /// <param name="date">The string to be validated</param>
        /// <returns>Returns true if the input string is not a valid date and false if it is</returns>
        protected bool ValidateDate(string date)
        {
            DateTime result;
            DateTime.TryParse(date, out result);
            if (result == DateTime.MinValue || result > DateTime.Now) return true;
            return false;

        }

        /// <summary>
        /// Validates whether the input string represents an integer
        /// </summary>
        /// <param name="integer">The string to be validated</param>
        /// <returns>Returns true if the input string is not an integer and false if it is</returns>
        protected bool ValidateInteger(string integer)
        {
            int result;
            return !int.TryParse(integer, out result);
        }
    }
}